//
//  Entity.cpp
//  Sinnca Engine v2
//
//  Created by Ryan Oldis on 8/1/11.
//  Copyright 2011 Sinnca Studios. All rights reserved.
//

#include "Node.h"

#include "Texture.h"


entity::entity(std::string n, float x, float y, float z, float rx, float ry, float rz, float sx, float sy, float sz, float r, float g, float b, float a, bool d, texture* t, mesh* ob)
{
	name = n;
	
	xyz[0] = x;
	xyz[1] = y;
	xyz[2] = z;
	
	rot[0] = rx;
	rot[1] = ry;
	rot[2] = rz;
	
	scl[0] = sx;
	scl[1] = sy;
	scl[2] = sz;
	
	color[0] = r;
	color[1] = g;
	color[2] = b;
	color[3] = a;
	
	draw = d;
	
	tex = t;
	m = ob;
	
}


void entity::render()
{
	//glTranslatef(scl[0] / 2 *-1, scl[1] / 2 *-1, 0);
	//glPopMatrix();
	if (m == NULL)
	{
		glTranslatef(xyz[0], xyz[1], xyz[2]);
		glRotatef(1, rot[0], 0, 0);
		
		glColor4f(color[0], color[1], color[2], color[3]);
		
		glBegin(GL_QUADS);
		
		glTexCoord2i(0, 0);
		glVertex3f(0.0f, 0.0f, 0.0f);
		
		glTexCoord2i(1, 0);
		glVertex3f(scl[0], 0.0f, 0.0f);
		
		glTexCoord2i(1, 1);
		glVertex3f(scl[0], scl[1], 0.0f);
		
		glTexCoord2i(0, 1);
		glVertex3f(0.0f, scl[1], 0.0f);
		
		glEnd();
	}
	
	glLoadIdentity();
	
}


entity* checkEntity(lua_State* L, int ind)
{
	void* ud = 0;
	
	// check for table object
	luaL_checktype(L, ind, LUA_TTABLE);
	
	// push the key we're looking for (in this case, it's "__self")
	lua_pushstring(L, "__self");
	// get our table
	lua_gettable(L, ind);
	
	// cast userdata pointer to "Node" type
	ud = dynamic_cast<entity*>((entity*)lua_touserdata(L, -1));
	luaL_argcheck(L, ud != 0, ind, "Incompatible 'node' type...");
	
	return *((entity**)ud);
	
	/*
	void* ud = dynamic_cast<entity*>((entity*)lua_touserdata(L, ind));
	luaL_argcheck(L, ud != 0, ind, "An 'entity' type node is required...");
	
	return *((entity**)ud);
	 */
}

static int newEntity(lua_State* L)
{
	int n = lua_gettop(L);
	if (n != 2)
	{
		return luaL_error(L, "You need to name this entity...");
	}
	
	luaL_checktype(L, 1, LUA_TTABLE);
	
	
	lua_newtable(L);
	
	lua_pushvalue(L, 1);
	lua_setmetatable(L, -2);
	
	lua_pushvalue(L, 1);
	lua_setfield(L, 1, "__index");
	 
	
	entity** en = (entity**)lua_newuserdata(L, sizeof(entity*));
	*en = new entity(luaL_checkstring(L, 2));
	
	
	luaL_getmetatable(L, "entity");
	lua_setmetatable(L, -2);
	
	lua_setfield(L, -2, "__self");
	
	
	lua_setglobal(L, luaL_checkstring(L, 2));
	
	
	return 1;
}

static int setG(lua_State* L)
{
	int n = lua_gettop(L);
	entity* en = checkEntity(L, 1);
	
	if (n == 4)
	{
		en->xyz[0] = (float)luaL_checknumber(L, 2);
		en->xyz[1] = (float)luaL_checknumber(L, 3);
		en->xyz[2] = (float)luaL_checknumber(L, 4);
	}
	
	return 0;
}

static int setR(lua_State* L)
{
	int n = lua_gettop(L);
	entity* en = checkEntity(L, 1);
	
	if (n == 4)
	{
		en->rot[0] = (float)luaL_checknumber(L, 2);
		en->rot[1] = (float)luaL_checknumber(L, 3);
		en->rot[2] = (float)luaL_checknumber(L, 4);
	}
	
	return 0;
}

static int setS(lua_State* L)
{
	int n = lua_gettop(L);
	entity* en = checkEntity(L, 1);
	
	if (n == 4)
	{
		en->scl[0] = (float)luaL_checknumber(L, 2);
		en->scl[1] = (float)luaL_checknumber(L, 3);
		en->scl[2] = (float)luaL_checknumber(L, 4);
	}
	
	return 0;
}

static int setCol(lua_State* L)
{
	int n = lua_gettop(L);
	
	entity* en = checkEntity(L, 1);
	
	if (n == 4 || n == 5)
	{
		en->color[0] = (float)luaL_checknumber(L, 2);
		en->color[1] = (float)luaL_checknumber(L, 3);
		en->color[2] = (float)luaL_checknumber(L, 4);
		
	}
	if (n == 5)
	{
		en->color[3] = (float)luaL_checknumber(L, 5);
	}
	
	return 0;
}

static int setTex(lua_State* L)
{
	int n = lua_gettop(L);
	if (n == 2)
	{
		entity* en = checkEntity(L, 1);
		texture* tx = checkTexture(L, 2);
		
		en->tex = tx;
	}
	
	return 0;
}



static int movG(lua_State* L)
{
	int n = lua_gettop(L);
	entity* en = checkEntity(L, 1);
	
	if (n == 4)
	{
		en->xyz[0] += (float)luaL_checknumber(L, 2);
		en->xyz[1] += (float)luaL_checknumber(L, 3);
		en->xyz[2] += (float)luaL_checknumber(L, 4);
	}
	
	return 0;
}

static int movR(lua_State* L)
{
	int n = lua_gettop(L);
	entity* en = checkEntity(L, 1);
	
	if (n == 4)
	{
		en->rot[0] += (float)luaL_checknumber(L, 2);
		en->rot[1] += (float)luaL_checknumber(L, 3);
		en->rot[2] += (float)luaL_checknumber(L, 4);
	}
	
	return 0;
}

static int movS(lua_State* L)
{
	int n = lua_gettop(L);
	entity* en = checkEntity(L, 1);
	
	if (n == 4)
	{
		en->scl[0] += (float)luaL_checknumber(L, 2);
		en->scl[1] += (float)luaL_checknumber(L, 3);
		en->scl[2] += (float)luaL_checknumber(L, 4);
	}
	
	return 0;
}

static int clear(lua_State* L)
{
	int n = lua_gettop(L);
	entity* en = checkEntity(L, 1);
	
	if (n == 1)
	{
		delete en;
	}
	return 0;
}

static const luaL_Reg entityGc[] = {
	{"__gc", clear},
	{NULL, NULL}
};

static const luaL_Reg entityFuncs[] = {
	
	{"new", newEntity},
	{"setG", setG},
	{"setR", setR},
	{"setS", setS},
	{"setCol", setCol},
	{"setTex", setTex},
	{"movG", movG},
	{"movR", movR},
	{"movS", movS},
	{NULL, NULL}
};

void registerEntity(lua_State* L)
{
	/*
	luaL_register(L, "entity", entityFuncs);
	lua_pushvalue(L,-1);
	lua_setfield(L, -2, "__index");
	*/
	
	luaL_newmetatable(L, "entity");
	
	//luaL_register(L, 0, entityGc);
	luaL_register(L, 0, entityFuncs);
	lua_pushvalue(L, -1);
	
	lua_setfield(L, -2, "__index");
	
	
	
	luaL_register(L, "entity", entityFuncs);
	
	
}
